メインコンテンツに移動

メインナビゲーション

  • ホーム
  • サイトマップ
  • ビデオ
  • ご連絡

パンくず

  • ホーム
  • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成

Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成

drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
drupal
video
customization
Views

やりたいこと:カスタムデータをモジュール(Views)で表示したい

  • カスタムテーブル(例:custom_table)のみを作成します(Drupalのコンテンツタイプで定義していない)
    • Drupalのエンティティタイプの定義はしない
    • 単純なテーブル(custom_table)をデータベースに作成
      custom_tableテーブルをDBに作成のみ、エンティティタイプの定義をしない
  • モジュール(Views)がデータを検索して表示するには、何らかのデータタイプ(エンティティタイプ)が必要
    • モジュール(Views)がターゲットデータのタイプ選択が必要
      モジュール(Views)がターゲットデータのタイプが必要

解決方法:hook_views_data()の”join”パラメーターで既存のコンテンツタイプ(例:node)の利用

  • モジュール(Views)が既存のコンテンツタイプ(node)の検索、データ表示ができます
  • カスタムテーブル(custom_table)がnodeにjoinすれば、モジュール(Views)でのデータの検索、表示ができるようになります
  • ここで、hook_views_data()を実装してnodeへのjoinカスタムモジュールを作成しました(custom_table.zip)
    hook_views_data()の実装でnodeにカスタムテーブルをjoinしてVewsでデータ検索、表示
  • hook_views_data()の実装は比較的に簡単で、カスタムテーブル(custom_table)のデータを定義します
    
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                    'join' => array(            // Join with node table
                        'node' => array(
                            'left_field' => 'title',
                            'field' => 'category',
                        )
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'desc' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }

hook_views_data()の”join”定義がcustom_table側で行い、Viewsがnode側のデータ検索を行います

  • 上記定義はcustom_table側で行いました。
  • モジュール(Views)がnodeタイプ(Article)をターゲットしてデータ検索を行います
    • custom_tableのデータをターゲットすることはできないからです(custom_tableがコンテンツタイプではない)
  • nodeタイプ(Article)とcustom_tableの”JOIN”キーは "node.title = custom_table.category" となります
  • Viewsでノード(node)データ検索フィルター:title="cate-a"をすればカスタムテーブルのデータの表示ができるようになります
    // custom_tableのjoin結果(Viewsの検索SQL)
    SELECT 
    	custom_table.id AS custom_table_id, 
    	custom_table.category AS custom_table_category, 
    	custom_table.desc AS custom_table_desc, 
    	node.created AS node_created
    FROM 
    	{node} node
    	LEFT JOIN {custom_table} custom_table ON node.title = custom_table.category
    WHERE 
    	node.status = '1' 
    	AND (node.type IN  ('article')) 
    	AND (node.title LIKE 'cate-a' )
    ORDER BY node_created DESC
    LIMIT 10 OFFSET 0

     

 

 

添付 サイズ
custom_table.zip (1.51 KB) 1.51 KB
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
drupal
video
development

Drupalのモジュール(Views)でカスタムテーブルデータ方法方法2:hook_views_data_alter()の「relationship」設定

  • やりたいこととhook_views_data()実装の方法などは前回の記事で紹介しました
    • Drupalのモジュール(Views)でカスタムデータ表示1:hook_views_data()の”JOIN”設定
  • 今回はhook_views_dataの「join」定義ではなく、hook_views_data_alter()の「relationship」定義でcustom_tableとjoinして、データ検索、表示することができます
    /**
     * Implements hook_views_api().
     */
    function custom_table_views_api()
    {
        return array(
            'api' => 3,
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function custom_table_views_data_alter(&$data)
    {
        $d = $data;
        // nodeタイプの"title"にリレーションシップ関連をつける
        $data['node']['title']['relationship'] = array(
            'handler' => 'views_handler_relationship',
            'base' => 'custom_table',
            'title' => 'Custom Table Category',
            'base field' => 'category',
        );
    }
    
    /**
     * Implements hook_views_data().
     */
    function custom_table_views_data()
    {
        $table = array(
            'custom_table' => array(
                'table' => array(
                    'group' => 'custom_table',
                    'base' => array(
                        'field' => 'id',  //Primary key
                        'title' => t('Test Data ID'),
                        'help' => t('The Id for the test data'),
                    ),
                ),
    
                'id' => array(
                    'title' => t('Custom Table ID'),
                    'help' => t('Test data Id field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_numeric' ),
                    'sort' => array('handler' => 'views_handler_sort'),
                 ),
    
                'category' => array(
                    'title' => t('Category'),
                    'help' => t('The category that refer to node'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array('handler' => 'views_handler_filter_string' ),
                    'sort' => array( 'handler' => 'views_handler_sort' ),
                ),
                'description' => array(
                    'title' => t('Description'),
                    'help' => t('Test data description field'),
                    'field' => array('click sortable' => TRUE, ),
                    'filter' => array( 'handler' => 'views_handler_filter_string' ),
                    'sort' => array('handler' => 'views_handler_sort' ),
                ),
    
            )
        );
        return $table;
    }
  • モジュール(Views)でnodeタイプ(Article)データをターゲットして、「リレーションシップ」でcustom_tableとjoinします
    hook_views_data_alter()を実装してcustom_tableとjoinし、データの検索/表示

hook_views_data_alter()の”relationship”定義がnode側で行い、Viewsがnode側のデータ検索を行います

  • nodeタイプ側で”relationship”を定義します(前回はcustom_table側)
  • custom_table側(hoo_views_data)の「join」定義を作成します(joinとrelationshipを同時に定義すると、検索結果がおかしくなる)
Embedded thumbnail for Drupalのモジュール(Views)でカスタムデータ表示2:hook_views_data()の”relationship”設定
drupal
video
customization
Views

やりたいこと:モジュール(Views)でサイト言語に従ってそれぞれの言語フィールドで表示させたいです

  • 例:中国語単語に、中国語/日本語/英語説明フィールドがDBテーブルにあります
  • モジュール(Views)で中国単語と説明一覧を表示します
  • 多言語サイト(中国語/日本語/英語)でユーザーが自由に言語選択ができます
  • 言語選択に従って中国語の中国語/日本語/英語説明フィールドを表示します
    Viewsでサイト言語選択に従ってそれぞれの言語説明フィールドを表示させます

hook_views_data()で選択された言語に従う言語の説明フィールドを選択してダミーフィールドとして表示させます

  • hook_views_data()実装でモジュール(Views)に様々なカスタマイズができます
    • Drupalのモジュール(Views)のチェックボックスのようなダミーカスタムフィールド作成
  • 上記例と同様にダミーフィールド(description)を追加します
    • 選択されたサイト言語を検出します
    • サイト言語と同じ説明フィールドをクエリにセットします
      /**
       * Implements hook_views_data_alter().
       */
      function drills_ch_vocabulary_views_data_alter(&$data)
      {
        // ダミーフィールド(Description)をViewsに追加
          $data['drills_ch_vocabulary']['description'] = array(
              'title' => t('Description'),
              'help' => t('Description depend on selected language'),
              'field' => array(
                  'handler' => 'field_handler_description',
                  'click sortable' => FALSE,
              ),
          );
      
      }
      
      // サイト言語より説明フィールドを選択し、クエリにセット
      class field_handler_description extends views_handler_field{
          Function query()
          {
              $this->ensure_my_table();
              $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
      
              // サイトの言語検出
              global $language;
              if( $language->language == 'en' ){ // 英語の場合
                  $field_name = "en_desc" ;
              } else if( $language->language == 'ja' ){ // 日本語の場合
                  $field_name = "ja_desc";
              } else {
                  $field_name = "ch_desc" ; // 中国語の場合
              }
      
              // 取得したフィールド名をクエリにセット
              $this->field_alias = $this->query->add_field($this->table_alias, $field_name, NULL, $params);
      
              $this->add_additional_fields();
          }
      }
      
  • 簡単にサイト言語より説明フィールドの選択ができ、クエリにセットすることができます


 

Embedded thumbnail for Drupalのモジュール(Views)でサイト言語に従って検索結果をそれぞれの言語で表示させる方法
drupal
customization
Views

やりたいこと:モジュール(Views)の検索、表示結果にボタン/チェックボックスのようなダミーフィールドを追加します

  • モジュール(Views)の検索結果のデータに対して何か加工したいことがあります
    • 例:モジュール(Flag)のように選択したノード/ユーザーにフラグを立てたいです
    • そのデータを別のテーブルに追加したり、削除したりすることがあります
  • 今回の実装例は単語検索一覧から自分の単語帳にコピーするロジックをモジュール(Views)に追加します
    モジュール(Views)が検索した結果にチェックボックスのようなフィールドを追加

hook_views_data_alter()の実装でダミーフィールド(チェックボックス)を検索結果に追加

  • 検索結果一覧に何かを追加するにはViewsにカスタムフィールドを追加する必要があります
  • カスタムフィールド追加するには、hook_views_data_alter()を実装すれば良いです
    /**
     * Implements hook_views_api().
     */
    function YOUR_MODULE_NAME_views_api()
    {
        return array(
            'api' => 3,
            'path' => drupal_get_path('module', 'YOUR_MODULE_NAME') . '/views',
        );
    }
    
    /**
     * Implements hook_views_data_alter().
     */
    function YOUR_MODULE_NAME_views_data_alter(&$data)
    {
        $d = $data;
        $data['ch_vocabulary']['add_to_my_vocabulary'] = array(
            'title' => t('Add to My Vocabulary'),
            'help' => t('Add this vocabulary to My Vocabulary'),
            'field' => array(
                'handler' => 'add_vocabulary_to_my_vocabulary_handler',
            ),
        );
    }
    
    /**
     * チェックボックス作成用のハンドル
     */
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    … // ajaxの処理
                ),
            );
            return render($form) ;
        }
    }
    
  • カスタムフィールドをViewsに追加するには、3ステップでできます
    • hook_views_api()の実装でViewsのカスタマイズ開始を宣言します
    • hook_views_data_alter()実装でカスタムフィールド(チェックボックス)を追加します
    • views_handler_fieldの実装でフィールド(チェックボックス)のレンダリングを行います

ダミーフィールド作成時にDBへのクエリを行わないことが記述する必要があります

  • 上記ロジックで実装して、Viewsの設定画面でカスタムフィールド追加後に、DBエラーが発生します
    カスタムフィールドのDBクエリが止めていないため、実テーブルにデータ取得時にエラー発生
  • hook_views_data_alter()でカスタムフィールド追加するときに、実テーブルのフィールドに関連付け設定が必要です("real field")。
  • ダミーフィールドなので、当然実フィールドがないです。定義することはできません。Viewsが実行時にそのカラムが見つからないエラーが発生します
  • ここで、Viewsの実行時にこのフィールドをクエリに加えないよう設定する必要があります
    class add_vocabulary_to_my_vocabulary_handler extends views_handler_field{
        function query()
        {
            // 何もないで、このフィールドをクエリに加えない
        }
    
        function render($value){
            $form['add_to_my_vocabulary'] = array(
                '#type' => 'checkbox',
                '#title' => 'Add',
                '#ajax' => array(
                    'callback' => 'add_to_my_vocabulary',
                    'effect' => 'fade',
                    …
                ),
            );
            return render($form) ;
        }
    }
  • views_handler_fieldの「function query()」をオーバーライドして、何も書かずにすればよいです
ホーム

古松

検索

Article Category

  • apache(7)
  • css(19)
  • drupal(295)
  • Electron(4)
  • html(34)
  • javascript(27)
  • laravel(4)
  • linux(5)
  • macOS(2)
  • mysql(13)
  • php(19)
  • python(4)
  • SEO(12)
  • video(72)
  • Visual Studio Code(4)
  • windows(13)
  • wordpress(32)